package org.zhuzx.util;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.remoting.RemoteAccessException;

/**
 * @author zhuzx 2022/7/7
 */
@ApiModel
public abstract class AbstractResult {

	@ApiModelProperty(value = "成功时统一返回[" + SUCCESS_MSG_VALUE + "]，失败的情况会返回具体的错误原因，" +
			"前端收到失败错误码时必须将错误描述的原文展示给用户。", position = 2)
	protected String msg;
	@ApiModelProperty(value = "额外的数据体", position = 3)
	protected Object data;

	/** 默认的成功提示文本 */
	protected static final String SUCCESS_MSG_VALUE = "操作成功";

	public abstract boolean isSuccess();

	/**
	 * 断言结果是成功的，失败则抛出RuntimeException。
	 * @param bizErrMsgPrefix 在抛出的异常原因（msg）前面加一个更详细的业务描述，可为空。
	 * @return 返回自身，不会修改（仅方便链式调用）。
	 */
	public AbstractResult assertSuccess(String bizErrMsgPrefix) {
		if (!isSuccess()) {
			String msgForReport = msg;
			if (GeneralUtil.isNotBlank(bizErrMsgPrefix)) {
				bizErrMsgPrefix = bizErrMsgPrefix.trim();
				String last = String.valueOf(bizErrMsgPrefix.charAt(bizErrMsgPrefix.length() - 1));
				//若传入的前缀未携带分隔标点，则用中文冒号将它和msg连接。
				String connector = last.matches(UnifiedConstants.REGEX_PUNCTUATION_SEPARATION) ? "" : "：";
				msgForReport = bizErrMsgPrefix + connector + msg;
			}
			throw new RemoteAccessException(msgForReport);
		}
		return this;
	}

	public String getMsg() {
		return msg;
	}

	public Object getData() {
		return data;
	}

	/**
	 * 判断远程结果为成功后返回data数据，若远程结果为失败则抛错。<br>
	 * 也就是说，本方法不会返回null，除非原始数据确实未打算返回有效的data。
	 */
	public Object assertSuccessAndGetData() {
		return assertSuccess(null).getData();
	}

}